
volume_header = [%(
eb58902d4656452d46532d00020800000000000000f800003f00ff008000010000000000e01f0000
000000000000000001000600000000000000000000000000800029000000004e4f204e414d452020
2020464154333220202033c98ed1bcf47b8ec18ed9bd007ca0fb7db47d8bf0ac9840740c48740eb4
0ebb0700cd10ebefa0fd7debe6cd16cd190000000000000000000000000000000000000000000000
3bd66749292ed84a8399f6a339e3d00100001002000000000000c002000000000000700300000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000d0a52656d6f7665206469736b73206f72206f7468657220
6d656469612eff0d0a4469736b206572726f72ff0d0a507265737320616e79206b657920746f2072
6573746172740d0a0000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000007878787878787878787878787878787878787878787878787878787878787878
78787878787878787878787878787878787878787878787878787878787878787878787878787878
7878787878787878ffffffffffffffffffffffffffffffffffffff001f2c55aa
).delete("\n")].pack("H*")

fve_header = [%(
2d4656452d46532d3e00020004000400000020040000000000000000100000000000100200000000
0000c002000000000000700300000000000011020000000098030000010000003000000098030000
9d741575626b6a448609e461ac9c8b3b42000000008000004dbe2a92b8e4d00118000f000f000100
000011020000000000200000000000003e0007000200010053004500560045004e00200042004900
54004c004f0043004b00450052002000300031002f00300039002f0032003000310035000000e000
020008000100880a7dfcb963ff40a31f67e865794a263018fda4b8e4d001000000206c0000000300
0100011000007e237a2aefe43ace0d1a3dfe90e4d347500000000500010090de09a4b8e4d0010200
0000372139682c273872d1af0d7cfae5a85fe856af890c642e5ec4f195580b7fde1c00c1b01b0884
a432294f09d96531a3bffee92c653c6d8a4f62d7e888500000000500010090de09a4b8e4d0010300
00000ce9565de838333811caacb594662fddf1fbc7fd4a2792646d918196307b7305083c47ab6f32
f91b7b0050b98c27a2ad6bf0884306389e15aa771e7cd000020008000100e219e43f2baf3c40a275
ce93a895876a70799eb2b8e4d001000000025c0000000400010002200000500000000500010090de
09a4b8e4d0010600000013951bd6f84f1ff002c6e1080daf91ebf938b554b9dde6ceaef4a3ccce73
7fd526ceb00bb39233689942e31dc2f17dcb6e7f5955e880a753ecbe6661500000000500010090de
09a4b8e4d00107000000e2b4c5db81a0d0fc5f1a8f13a2906da7561fce73bc0be872fa450a26aa70
f00af575ff72e29565bd7e54cc7281f16e28c91664d69d1ac0349817f03a700003000500010090de
09a4b8e4d00108000000a963bb6baad0198476db06ef28cdffbbff46f2bd37e94328fb9610a63db2
c81a222a402801a43bb83d4c78ac349f8a0c911f8b82f4f74ed801d81911402b29351f8f1fb74135
928326c12c0c3e92d5ebfcba3a2e865208de579985d7f200020008000100000e3e29fa338c409d4d
edf0a07e3af770b7400a1d1bd1010000000822000000020001004400690073006b00500061007300
730077006f007200640000005c0000000300010000100000410c97f721e4203936b2da255c94f2d3
400000000500010060cf7a091d1bd1013f00000034912ac8588851df6a4fc4e116153484c193daab
d02518fa2403fd43eebeeced237fabd4fb3c6b5b8c5829e3500000000500010060cf7a091d1bd101
40000000490277082603ea9b968cf1b7aa599140bf33bd2580fcf501bf67fdb9ee49fc44c0adf17c
21f7b5435a7a75bec6601b28ce3537d2607bf52207008620000000000000000020fc02009e1b2f8b
5000000005000100a4c7400a1d1bd10141000000db197743fdd35661f8e332c5fcfe93324080dd41
63a6efbf510e99984d2c42b2b9009efb9653c83c1ff0bad8fa38c0e0e2f791de8a8211af74cf2313
).delete("\n")].pack("H*")

recovery_password = '657096-479369-488587-457336-698588-612986-598950-103389'

fvek_dislocker_format = [%(
0080923550357e1cdd9f0810773a82001fdb332a0e577d90931ea627d2df
355308c32f20e94d434edcf28f64798ee530cc63220bee6277e988e43638
be9530d70524
).delete("\n")].pack("H*")

###
#
# This Test class emulate the header of a bitlocker drive and the fve header
#
###
class BitlockerDrive
  def initialize(volume_header, fve_header)
    @volume_header = volume_header
    @fve_header = fve_header
    @offset = 0
  end

  def seek(offset)
    @offset = offset
  end

  def read(_size)
    if @offset == 0
      @volume_header
    else
      @fve_header
    end
  end
end

RSpec.describe Rex::Parser::BITLOCKER do
  Bitlocker = Rex::Parser::BITLOCKER.new(BitlockerDrive.new(volume_header,
                                                             fve_header))
  ##
  # Decrypt
  ##
  it "Extract and decrypt recovery key from recovery password" do
    result = Bitlocker.fvek_from_recovery_password_dislocker(recovery_password)
    expect(result).to eq fvek_dislocker_format
  end
end
